package hikari.objects3d;

import com.gooddies.wiring.Wiring;
import hikari.gui.assets.AssetsTree;
import hikari.gui.panels.AnimationEditPanel;
import hikari.hcomponents.HComponent;
import hikari.managers.Manager3D;
import hikari.persistence.file.FileSection;
import hikari.persistence.file.PersistenceSection;
import hikari.utils.Utils;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.swig.jirr.IAnimatedMesh;
import org.swig.jirr.IAnimatedMeshSceneNode;
import org.swig.jirr.ISceneManager;
import org.swig.jirr.ITriangleSelector;

/**
 * @author Dmitry
 */
public class Custom3DObject extends GeometricObject {

    private String relativeModelPath;
    private IAnimatedMeshSceneNode node;
    private boolean immidiatelyAnimated = false;
    private String selectedAnimationTrac = null;

    public Custom3DObject(IAnimatedMeshSceneNode node) {
        super("Object", true);
        this.node = node;
        init3dModel();
    }

    public Custom3DObject(String name, IAnimatedMeshSceneNode node) {
        super(name);
        this.node = node;
        init3dModel();
    }

    public String getSelectedAnimationTrac() {
        return selectedAnimationTrac == null ? "" : selectedAnimationTrac;
    }

    public void setSelectedAnimationTrac(String selectedAnimationTrac) {
        this.selectedAnimationTrac = selectedAnimationTrac;
    }

    public boolean isImmidiatelyAnimated() {
        return immidiatelyAnimated;
    }

    public void setImmidiatelyAnimated(boolean immidiatelyAnimated) {
        this.immidiatelyAnimated = immidiatelyAnimated;
    }

    public String getRelativeModelPath() {
        return relativeModelPath;
    }

    public Custom3DObject setRelativeModelPath(String relativeModelPath) {
        this.relativeModelPath = relativeModelPath;
        return this;
    }

    public IAnimatedMeshSceneNode getNode() {
        return node;
    }

    public Custom3DObject setNode(IAnimatedMeshSceneNode node) {
        this.node = node;
        return this;
    }

    private void init3dModel() {
        ISceneManager scene = node.getSceneManager();
        ITriangleSelector selector = scene.createTriangleSelector(node.getMesh(), node);
        node.setTriangleSelector(selector);
        node.setParent(scene.getRootSceneNode());
        setMeshSceneNode(node);
        stopAnimation();
    }

    public void stopAnimation() {
        node.setFrameLoop((int) node.getFrameNr(), (int) node.getFrameNr());
    }

    private AnimationEditPanel getAnimationEditPanel() {
        AnimationEditPanel panel = Wiring.getComponent(AnimationEditPanel.class);
        panel.setModel(this);
        panel.update();
        return panel;
    }

    @Override
    public List<HComponent> getEditPanels() {
        List<HComponent> panels = super.getEditPanels();
        panels.add(getAnimationEditPanel());
        return panels;
    }

    @Override
    public void writeData(FileSection section) throws IOException {
        super.writeData(section);
        section.writeString("path", getRelativeModelPath());
        PersistenceSection animSection = section.createNewSection("anim");
        animSection.writeBoolean("immAnim", isImmidiatelyAnimated());
        animSection.writeBoolean("lp", getNode().getLoopMode());
        animSection.writeString("selTrk", getSelectedAnimationTrac());
        animSection.close();
    }

    @Override
    public String objectType() {
        return "cModel";
    }

    public static Custom3DObject loadModelByPath(String absolutePath, ISceneManager sceneManager) {
        Utils utils = Wiring.getComponent(Utils.class);
        if (!new File(absolutePath).exists()) {
            utils.errorMessage("Object with path " + absolutePath + " does not exist");
            return null;
        }
        ISceneManager scene = Wiring.getComponent(Manager3D.class).getSceneManager();
        IAnimatedMesh mesh = scene.getMesh(absolutePath);
        IAnimatedMeshSceneNode node = scene.addAnimatedMeshSceneNode(mesh);
        Custom3DObject object3d = new Custom3DObject(utils.getFileNameWithoutExtension(absolutePath), node);
        object3d.setRelativeModelPath(Wiring.getComponent(AssetsTree.class).getRelativeAssetsPath(absolutePath));
        return object3d;
    }
}